﻿using netDxf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace GluePathModule
{
    
    public class GluePathItemArc : GluePathItemBase
    {
        [Description("圆弧的第一点"), Category("圆弧设定")]
        public PointData PosStart
        {
            get;
            set;
        }
        [Description("圆弧的第二点"), Category("圆弧设定")]
        public PointData PosMid
        {
            get;
            set;
        }
        [Description("圆弧的第三点"), Category("圆弧设定")]
        public PointData PosEnd
        {
            get;
            set;
        }
        [Description("圆弧的第一点"), Category("圆弧转换后")]
        public PointData PosStartTransfer
        {
            get;
            set;
        }
        [Description("圆弧的第二点"), Category("圆弧转换后")]
        public PointData PosMidTransfer
        {
            get;
            set;
        }
        [Description("圆弧的第三点"), Category("圆弧转换后")]
        public PointData PosEndTransfer
        {
            get;
            set;
        }
        [Description("圆弧U轴跟随角度"), Category("圆弧设定")]
        public bool U不跟随
        {
            get;
            set;
        }
        [Browsable(false)]
        public int iDrawStep
        {
            get;
            set;
        }
        [Browsable(false)]
        public bool bUseZheight
        {
            get;
            set;
        }
        [Browsable(false)]
        public string UseZheightName
        {
            get;
            set;
        }
        public GluePathItemArc()
        {
            iDrawStep = 0;
            Name = "";
            Remark = "";
            UseZheightName = "";
            PosStart = new PointData();
            PosMid = new PointData();
            PosEnd = new PointData();
        }
        public override void DrawItem(DrawerControl drawer, DrawMode drawMode = DrawMode.UnitIsSelected)
        {
            base.DrawItem(drawer);
            if (drawMode == DrawMode.Background)
            {
                drawer.DrawArc(new System.Drawing.Pen(System.Drawing.Color.Gray, 1), PosStart.X, PosStart.Y, PosMid.X, PosMid.Y, PosEnd.X, PosEnd.Y);
                return;
            }
            else if(drawMode == DrawMode.UnitIsNotSelect)
            {
                drawer.DrawArc(new System.Drawing.Pen(System.Drawing.Color.White, 3), PosStart.X, PosStart.Y, PosMid.X, PosMid.Y, PosEnd.X, PosEnd.Y);
                return;
            }

            if (空动作路径)
            {
                drawer.DrawArc(new System.Drawing.Pen(System.Drawing.Color.Blue, 3), PosStart.X, PosStart.Y, PosMid.X, PosMid.Y, PosEnd.X, PosEnd.Y);
            }
            else
            {
                drawer.DrawArc(new System.Drawing.Pen(System.Drawing.Color.Green, 3), PosStart.X, PosStart.Y, PosMid.X, PosMid.Y, PosEnd.X, PosEnd.Y);
            }
            if (Select)
            {
                
                drawer.DrawPoint(new System.Drawing.Pen(System.Drawing.Color.Red, 2), PosStart.X, PosStart.Y, 0.5);
                drawer.DrawPoint(new System.Drawing.Pen(System.Drawing.Color.Red, 2), PosMid.X, PosMid.Y, 0.5);
                drawer.DrawPoint(new System.Drawing.Pen(System.Drawing.Color.Red, 2), PosEnd.X, PosEnd.Y, 0.5);
            }

        }

        public override bool IsOnSelect(double dPosX, double dPosY, double dJudageDis)
        {
            double CenterX, CenterY, R;
            GetCircle(PosStart.X, PosStart.Y, PosMid.X, PosMid.Y, PosEnd.X, PosEnd.Y, out CenterX, out CenterY, out R);


            double dDistance = Math.Abs((GetDisFrom2Points(dPosX, dPosY, CenterX, CenterY) - R));

            double dStartAnglePi = Math.Atan2(PosStart.Y - CenterY, PosStart.X - CenterX);
            double dStartAngle = 180 * dStartAnglePi / Math.PI;
            double dMidAnglePi = Math.Atan2(PosMid.Y - CenterY, PosMid.X - CenterX);
            double dMidAngle = 180 * dMidAnglePi / Math.PI;
            double dMidAnglePi1 = Math.Atan2(dPosY - CenterY, dPosX - CenterX);
            double dMidAngle1 = 180 * dMidAnglePi1 / Math.PI;
            double dEndAnglePi = Math.Atan2(PosEnd.Y - CenterY, PosEnd.X - CenterX);
            double dEndAngle = 180 * dEndAnglePi / Math.PI;
            double dSweeAngle, dSweeAngle1;
            bool bInMidAngle = false;
            dSweeAngle = dEndAngle - dStartAngle;
            dSweeAngle1 = dEndAngle - dStartAngle;
            if (dSweeAngle > 0)
            {
                if (dMidAngle > dStartAngle && dMidAngle < dEndAngle)
                {
                    dSweeAngle = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle = -(360 - (dEndAngle - dStartAngle));
                }
            }
            else
            {
                if (dMidAngle < dStartAngle && dMidAngle > dEndAngle)
                {
                    dSweeAngle = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle = (360 - (dStartAngle - dEndAngle));
                }
            }

            if (dSweeAngle1 > 0)
            {
                if (dMidAngle1 > dStartAngle && dMidAngle1 < dEndAngle)
                {
                    dSweeAngle1 = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle1 = -(360 - (dEndAngle - dStartAngle));
                }
            }
            else
            {
                if (dMidAngle1 < dStartAngle && dMidAngle1 > dEndAngle)
                {
                    dSweeAngle1 = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle1 = (360 - (dStartAngle - dEndAngle));
                }
            }
            if ((dSweeAngle > 0 && dSweeAngle1 > 0) || (dSweeAngle < 0 && dSweeAngle1 < 0))
                bInMidAngle = true;
            else
                bInMidAngle = false;

            if ((dDistance < dJudageDis) & bInMidAngle)
            {
                Select = true;
                return Select;
            }
            else
            {
                //Select = false;
                return Select;
            }
            //return true;

        }
        public double GetDisFrom2Points(double x1, double y1, double x2, double y2)
        {
            return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        }

        public bool GetCircle(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3,
          out double dCenterX, out double dCenterY, out double dR)
        {
            dCenterX = 0.0;
            dCenterY = 0.0;
            dR = 0.0;
            double dA1, dB1, dA2, dB2;
            double dCrossX = 0.0;
            double dCrossY = 0.0;
            //Line1
            bool bLine1Ok = GetLine(dX1, dY1, dX2, dY2, out dA1, out dB1);

            //Line1
            bool bLine2Ok = GetLine(dX2, dY2, dX3, dY3, out dA2, out dB2);
            //Cross

            if (bLine1Ok && bLine2Ok)
            {
                LineCross(dA1, dB1, dA2, dB2, out dCrossX, out dCrossY);
            }
            else
            {
                if (bLine1Ok == false && bLine2Ok == false)
                {
                    return false;
                }
                if (bLine1Ok == false)
                {
                    dCrossX = dB1;
                    dCenterY = dCrossX * dA2 + dB2;
                }
                if (bLine2Ok == false)
                {
                    dCrossX = dB2;
                    dCenterY = dCrossX * dA1 + dB1;
                }
            }
            dCenterX = dCrossX;
            dCenterY = dCrossY;
            dR = Math.Sqrt((dX1 - dCrossX) * (dX1 - dCrossX) + (dY1 - dCrossY) * (dY1 - dCrossY));
            return true;
        }
        private bool GetLine(double dX1, double dY1, double dX2, double dY2, out double dA, out double dB)
        {
            dA = 0.0;
            dB = 0.0;
            double dTempA, dTempB;
            double dX, dY;
            if (Math.Abs(dX1 - dX2) < 0.00000001)
            {
                dA = 0.0;
                dB = (dY1 + dY2) / 2.0;
                return true;
            }
            if (Math.Abs(dY1 - dY2) < 0.00000001)
            {
                dA = 0.0;
                dB = (dX1 + dX2) / 2.0;
                return false;
            }
            dTempA = (dY2 - dY1) / (dX2 - dX1);
            dTempB = dY1 - dA * dX1;
            //计算直线中点
            dX = (dX1 + dX2) / 2.0;
            dY = (dY1 + dY2) / 2.0;
            //中垂线
            dA = -1 / dTempA;
            dB = dY - dA * dX;
            return true;

        }
        private void LineCross(double dA1, double dB1, double dA2, double dB2, out double dCrossX, out double dCrossY)
        {
            dCrossX = 0.0;
            dCrossY = 0.0;
            dCrossX = (dB1 - dB2) / (dA2 - dA1);
            dCrossY = dA1 * dCrossX + dB1;
        }

        public override bool GetLastPoint(out double dPosX, out double dPosY, out double dPosZ, out double dPosU)
        {
            dPosX = PosEnd.X;
            dPosY = PosEnd.Y;
            dPosZ = PosEnd.Z;
            dPosU = PosEnd.U;
            return true;
        }
        public override bool GetFirstPoint(out double dPosX, out double dPosY, out double dPosZ, out double dPosU)
        {
            //double dZHeight = Pos1Z;
            //if (pathUnitCurrent.dicZheightItems.ContainsKey(UseZheightName))
            //{
            //    dZHeight = pathUnitCurrent.dicZheightItems[UseZheightName].MotorZData;
            //}
            dPosX = PosStart.X;
            dPosY = PosStart.Y;
            dPosZ = PosStart.Z;
            dPosU = PosStart.U;
            return true;
        }
      
        public override GluePathItemBase CopyItem()
        {
            GluePathItemArc itemNew = (GluePathItemArc)MemberwiseClone();
            itemNew.PosStart = new PointData(PosStart);
            itemNew.PosStartTransfer = new PointData(PosStartTransfer);
            itemNew.PosMid = new PointData(PosMid);
            itemNew.PosMidTransfer = new PointData(PosMidTransfer);
            itemNew.PosEnd = new PointData(PosEnd);
            itemNew.PosEndTransfer = new PointData(PosEndTransfer);

            return itemNew;
        }
        override public GluePathItemBase Paste()
        {

            return CopyItem();
        }
        public override void OffSetItem(double dOffSetX, double dOffSetY)
        {
            PosStart.X = PosStart.X + dOffSetX;
            PosStart.Y = PosStart.Y + dOffSetY;
            PosMid.X = PosMid.X + dOffSetX;
            PosMid.Y = PosMid.Y + dOffSetY;
            PosEnd.X = PosEnd.X + dOffSetX;
            PosEnd.Y = PosEnd.Y + dOffSetY;
        }
        override public void PathUnitMouseDown(double dMouseX, double dMouseY, double dScandle)
        {
            if (Select == false)
                return;
            //if (iAdjustStep == 0)
            {
                double dDistance1 = Math.Sqrt((dMouseX - PosStart.X) * (dMouseX - PosStart.X) + (dMouseY - PosStart.Y) * (dMouseY - PosStart.Y));
                double dDistance2 = Math.Sqrt((dMouseX - PosMid.X) * (dMouseX - PosMid.X) + (dMouseY - PosMid.Y) * (dMouseY - PosMid.Y));
                double dDistance3 = Math.Sqrt((dMouseX - PosEnd.X) * (dMouseX - PosEnd.X) + (dMouseY - PosEnd.Y) * (dMouseY - PosEnd.Y));
                if (dDistance1 < (5 / dScandle) || dDistance2 < (5 / dScandle) || dDistance3 < (5 / dScandle))
                {
                    if (dDistance1 < dDistance2)
                    {
                        if (dDistance1 < dDistance3)
                        {
                            iAdjustStep = 1;
                        }
                        else
                        {
                            iAdjustStep = 2;
                        }
                    }
                    else
                    {
                        if (dDistance2 < dDistance3)
                        {
                            iAdjustStep = 3;
                        }
                        else
                        {
                            iAdjustStep = 2;
                        }
                    }
                }
            }
        }
        override public void PathUnitMouseMove(double dMouseX, double dMouseY)
        {
            if (Select == false)
                return;
            if (iAdjustStep == 1)
            {

                PosStart.X = dMouseX;
                PosStart.Y = dMouseY;

            }
            if (iAdjustStep == 2)
            {
                PosEnd.X = dMouseX;
                PosEnd.Y = dMouseY;

            }
            if (iAdjustStep == 3)
            {
                PosMid.X = dMouseX;
                PosMid.Y = dMouseY;

            }
        }
        override public void PathUnitMouseUp(double dMouseX, double dMouseY)
        {
            if (Select == false)
                return;
            if (iAdjustStep == 1)
            {

                PosStart.X = dMouseX;
                PosStart.Y = dMouseY;
                iAdjustStep = 0;
                //FormUpdate();

            }
            if (iAdjustStep == 2)
            {
                PosEnd.X = dMouseX;
                PosEnd.Y = dMouseY;
                iAdjustStep = 0;
                //FormUpdate();

            }
            if (iAdjustStep == 3)
            {
                PosMid.X = dMouseX;
                PosMid.Y = dMouseY;
                iAdjustStep = 0;
                //FormUpdate();

            }
        }
        
       

        
        private bool IsCW()
        {
            double xCenterPos; double yCenterPos; double dR;
            //m_bmpGraphic.Clear(Color.Black);
            if (GetCircle(PosStart.X, PosStart.Y, PosMid.X, PosMid.Y, PosEnd.X, PosEnd.Y, out xCenterPos, out yCenterPos, out dR) == false)
                return false;
            double dStartAnglePi = Math.Atan2(PosStart.Y - yCenterPos, PosStart.X - xCenterPos);
            double dStartAngle = 180 * dStartAnglePi / Math.PI;
            double dMidAnglePi = Math.Atan2(PosMid.Y - yCenterPos, PosMid.X - xCenterPos);
            double dMidAngle = 180 * dMidAnglePi / Math.PI;
            double dEndAnglePi = Math.Atan2(PosEnd.Y - yCenterPos, PosEnd.X - xCenterPos);
            double dEndAngle = 180 * dEndAnglePi / Math.PI;
            double dSweeAngle;
            dSweeAngle = dEndAngle - dStartAngle;
            if (dSweeAngle > 0)
            {
                if (dMidAngle > dStartAngle && dMidAngle < dEndAngle)
                {
                    dSweeAngle = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle = -(360 - (dEndAngle - dStartAngle));
                }
            }
            else
            {
                if (dMidAngle < dStartAngle && dMidAngle > dEndAngle)
                {
                    dSweeAngle = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle = (360 - (dStartAngle - dEndAngle));
                }
            }

            if (dSweeAngle > 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        public override void OffSetPos(double dOffSetX, double dOffSetY, double dOffSetZ)
        {
            PosStart.X = PosStart.X + dOffSetX;
            PosStart.Y = PosStart.Y + dOffSetY;
            PosStart.Z = PosStart.Z + dOffSetZ;

            PosMid.X = PosMid.X + dOffSetX;
            PosMid.Y = PosMid.Y + dOffSetY;
            PosMid.Z = PosMid.Z + dOffSetZ;

            PosEnd.X = PosEnd.X + dOffSetX;
            PosEnd.Y = PosEnd.Y + dOffSetY;
            PosEnd.Z = PosEnd.Z + dOffSetZ;
        }
        public override void SetZPos(double dSetPosZ)
        {

            PosStart.Z = dSetPosZ;


            PosMid.Z = dSetPosZ;


            PosEnd.Z = dSetPosZ;
        }
        public override void SetUPos(double dSetUPos)
        {

            PosStart.U = dSetUPos;


            PosMid.U = dSetUPos;


            PosEnd.U = dSetUPos;
        }
        public override void UpdateZheight(double dSetZPosZ)
        {
            if (bUseZheight == false)
                return;
            double dZHeight = 0.0;

            PosStart.Z = dZHeight;
            PosMid.Z = dZHeight;
            PosEnd.Z = dZHeight;
           
        }
        public override void WriteToDxf(DxfDocument dxfDocument)
        {
            double xCenterPos; double yCenterPos; double dR;
            //m_bmpGraphic.Clear(Color.Black);
            if (GetCircle(PosStart.X, PosStart.Y, PosMid.X, PosMid.Y, PosEnd.X, PosEnd.Y, out xCenterPos, out yCenterPos, out dR) == false)
                return ;
            return;
            double dStartAnglePi = Math.Atan2(PosStart.Y - yCenterPos, PosStart.X - xCenterPos);
            double dStartAngle = 180 * dStartAnglePi / Math.PI;
            double dMidAnglePi = Math.Atan2(PosMid.Y - yCenterPos, PosMid.X - xCenterPos);
            double dMidAngle = 180 * dMidAnglePi / Math.PI;
            double dEndAnglePi = Math.Atan2(PosEnd.Y - yCenterPos, PosEnd.X - xCenterPos);
            double dEndAngle = 180 * dEndAnglePi / Math.PI;
            double dSweeAngle;
            dSweeAngle = dEndAngle - dStartAngle;
            if (dSweeAngle > 0)
            {
                if (dMidAngle > dStartAngle && dMidAngle < dEndAngle)
                {
                    dSweeAngle = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle = -(360 - (dEndAngle - dStartAngle));
                }
            }
            else
            {
                if (dMidAngle < dStartAngle && dMidAngle > dEndAngle)
                {
                    dSweeAngle = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle = (360 - (dStartAngle - dEndAngle));
                }
            }
            netDxf.Entities.Arc arcTemp;
            netDxf.Entities.Circle circleTemp;

            if (dSweeAngle > 0)
            {
                arcTemp = new netDxf.Entities.Arc(new netDxf.Vector2(xCenterPos, yCenterPos), dR, dStartAngle, dEndAngle);
            }
            else
            {
                dStartAnglePi = Math.Atan2(PosStart.Y - yCenterPos, xCenterPos - PosStart.X);
                dStartAngle = 180 * dStartAnglePi / Math.PI;

                dEndAnglePi = Math.Atan2(PosEnd.Y - yCenterPos, xCenterPos - PosEnd.X);
                dEndAngle = 180 * dEndAnglePi / Math.PI;
                arcTemp = new netDxf.Entities.Arc(new netDxf.Vector2(xCenterPos, yCenterPos), dR, dStartAngle, dEndAngle);
                netDxf.Vector3 myNormal = new Vector3(0, 0, -1.0);
                arcTemp.Normal = myNormal;

            }


            if (this.空动作路径)
            {
                arcTemp.Color = new netDxf.AciColor(System.Drawing.Color.Blue);
            }
            else
            {
                arcTemp.Color = new netDxf.AciColor(System.Drawing.Color.Green);
            }

            dxfDocument.Entities.Add(arcTemp);
        }

        public override void GetItemMinMaxXY(out double dMinX, out double dMinY, out double dMaxX, out double dMaxY)
        {
            base.GetItemMinMaxXY(out dMinX, out dMinY, out dMaxX, out dMaxY);

            if (PosStart.X < PosMid.X)
            {
                if (PosStart.X < PosEnd.X)
                {
                    dMinX = PosStart.X;
                }
                else
                {
                    dMinX = PosEnd.X;
                }
            }
            else
            {
                if (PosEnd.X < PosMid.X)
                {
                    dMinX = PosEnd.X;
                }
                else
                {
                    dMinX = PosEnd.X;
                }
            }
            if (PosStart.Y < PosMid.Y)
            {
                if (PosStart.Y < PosEnd.Y)
                {
                    dMinY = PosStart.Y;
                }
                else
                {
                    dMinY = PosEnd.Y;
                }
            }
            else
            {
                if (PosEnd.Y < PosMid.Y)
                {
                    dMinY = PosEnd.Y;
                }
                else
                {
                    dMinY = PosMid.Y;
                }
            }

            if (PosStart.X > PosMid.X)
            {
                if (PosStart.X > PosEnd.X)
                {
                    dMaxX = PosStart.X;
                }
                else
                {
                    dMaxX = PosEnd.X;
                }
            }
            else
            {
                if (PosEnd.X > PosMid.X)
                {
                    dMaxX = PosEnd.X;
                }
                else
                {
                    dMaxX = PosMid.X;
                }
            }

            if (PosStart.Y > PosMid.Y)
            {
                if (PosStart.Y > PosEnd.Y)
                {
                    dMaxY = PosStart.Y;
                }
                else
                {
                    dMaxY = PosEnd.Y;
                }
            }
            else
            {
                if (PosEnd.Y > PosMid.Y)
                {
                    dMaxY = PosEnd.Y;
                }
                else
                {
                    dMaxY = PosMid.Y;
                }
            }
        }
        public override void UpdateEndPos(double dNewEndX, double dNewEndY)
        {
            PosEnd.X = dNewEndX;
            PosEnd.Y = dNewEndY;
        }
        public override void UpdateStartPos(double dNewStartX, double dNewStartY)
        {
            PosStart.X = dNewStartX;
            PosStart.Y = dNewStartY;
        }
        public override void PushItem(List<MotionItemBase> motionItems, GluePathGroup gluePathGroup, GluePathUnit gluePathUnit, int indexId, double dOffSetZ)
        {
            

            SpdData spdXYGlue = new SpdData();
            SpdData spdXYH=new SpdData();
            SpdData spdZH = new SpdData();
            

            double dFirstPosX, dFirstPosY, dFirstPosZ, dFirstPosU;
            GetFirstPoint(out dFirstPosX, out dFirstPosY, out dFirstPosZ, out dFirstPosU);

            #region 判断胶路类型
            bool bIsFirstItem = false;
            bool bisFinalItem = false;
            bool bContinueWithBeforeItem = false;
            bool bContinueWithAferItem = false;
            bool bIsContinueWithAferAndAfterIsOnGlue = false;
            if (indexId == 0)
            {
                bIsFirstItem = true;
            }
            if (indexId == (gluePathUnit.listContinueItems.Count - 1))
            {
                bisFinalItem = true;
            }
            if (indexId == 0)
            {
                
            }
            else
            {
                double dBeforeItemPosX, dBeforeItemPosY, dBeforeItemPosZ, dBeforeItemPosU;
                gluePathUnit.listContinueItems[indexId - 1].GetLastPoint(out dBeforeItemPosX, out dBeforeItemPosY,
                    out dBeforeItemPosZ, out dBeforeItemPosU);
                if (Math.Abs(dBeforeItemPosX - dFirstPosX) < 0.5 && Math.Abs(dBeforeItemPosY - dFirstPosY) < 0.5 && Math.Abs(dBeforeItemPosZ - dFirstPosZ) < 0.5)
                {
                    bContinueWithBeforeItem = true;
                }
            }
            if (indexId == (gluePathUnit.listContinueItems.Count - 1))
            {
                bContinueWithAferItem = false;
            }
            else
            {
                double dNextItemPosX, dNextItemPosY, dNextItemPosZ, dNextItemPosU;
                double dCurrentEndPosX, dCurrentEndPosY, dCurrentEndPosZ, dCurrentEndPosU;
                GetLastPoint(out dCurrentEndPosX, out dCurrentEndPosY, out dCurrentEndPosZ, out dCurrentEndPosU);
                gluePathUnit.listContinueItems[indexId + 1].GetFirstPoint(out dNextItemPosX, out dNextItemPosY,
                    out dNextItemPosZ, out dNextItemPosU);
                if (Math.Abs(dCurrentEndPosX - dNextItemPosX) < 0.5 && Math.Abs(dCurrentEndPosY - dNextItemPosY) < 0.5 && Math.Abs(dCurrentEndPosZ - dNextItemPosZ) < 0.5)
                {
                    bContinueWithAferItem = true;
                    if (gluePathUnit.listContinueItems[indexId + 1].空动作路径 == false && gluePathUnit.listContinueItems[indexId + 1].Disable == false)
                    {
                        bIsContinueWithAferAndAfterIsOnGlue = true;
                    }
                }
            }
            #endregion

            #region 速度设定

            if (使用单独涂胶速度)
            {
                spdXYGlue.dMoveSpd = 单独涂胶速度;
            }
            else
            {
                if (空动作路径)
                {
                    spdXYGlue.dMoveSpd = gluePathUnit.全局XY高速速度;
                }
                else
                {
                    spdXYGlue.dMoveSpd = gluePathUnit.全局涂胶速度;
                }
            }
            spdXYH.dStartSpd = gluePathUnit.全局开始速度;
            spdXYH.dMoveSpd = gluePathUnit.全局XY高速速度;
            spdXYH.dEndSpd = gluePathUnit.全局结束速度;
            spdXYH.dAcc = gluePathUnit.全局加速度;
            spdXYH.dDec = gluePathUnit.全局减速度;
            spdZH.dStartSpd = gluePathUnit.全局开始速度;
            spdZH.dMoveSpd = gluePathUnit.全局Z高速速度;
            spdZH.dEndSpd = gluePathUnit.全局结束速度;
            spdZH.dAcc = gluePathUnit.全局加速度;
            spdZH.dDec = gluePathUnit.全局减速度;
            if (bIsFirstItem && bisFinalItem)//只有一个点
            {
                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            if (bIsFirstItem && (!bContinueWithBeforeItem) && (bContinueWithAferItem) && (!bisFinalItem))//流程的第一个点和后面有连接
            {

                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;

            }
            if (!bIsFirstItem && (!bContinueWithBeforeItem) && (bContinueWithAferItem) && (!bisFinalItem))//流程中间点，没有和前面的连接，与后面的连接
            {

                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;

            }
            if (!bIsFirstItem && (bContinueWithBeforeItem) && (bContinueWithAferItem) && (!bisFinalItem))//流程中间点，和前面的连接，与后面的连接
            {

                spdXYGlue.dStartSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dEndSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            if (!bIsFirstItem && (bContinueWithBeforeItem) && (!bContinueWithAferItem) && (!bisFinalItem))//流程中间点，和前面的连接，没有与后面的连接
            {
                spdXYGlue.dStartSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;

            }
            if (!bIsFirstItem && (!bContinueWithBeforeItem) && (!bContinueWithAferItem) && (!bisFinalItem))//流程中间点，没有和前面的连接，没有与后面的连接
            {
                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            if (!bIsFirstItem && (bContinueWithBeforeItem) && (!bContinueWithAferItem) && (bisFinalItem))//流程最后一个线段，和前面连接
            {
                spdXYGlue.dStartSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            if (!bIsFirstItem && (!bContinueWithBeforeItem) && (!bContinueWithAferItem) && (bisFinalItem))//流程最后一个线段，没有和前面连接
            {
                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            #endregion


            TranferPosToCur(gluePathUnit, bContinueWithBeforeItem, motionItems,dOffSetZ);

            #region 轨迹设定


            if (bContinueWithBeforeItem == false)
            {
                MotionItemLine motionItemLineUp = new MotionItemLine(spdXYH,PosStartTransfer);
                motionItemLineUp.Point.Z = gluePathUnit.全局安全高度Z;
                motionItems.Add(motionItemLineUp);
                MotionItemLine motionItemLineStart = new MotionItemLine(spdZH, PosStartTransfer);
                motionItems.Add(motionItemLineStart);
                gluePathUnit.BeforeItemU = PosStartTransfer.U;

            }
            if (空动作路径 == false)
            {
                MotionItemOutput motionItemOutput = new MotionItemOutput();
                motionItemOutput.On = true;
                motionItems.Add(motionItemOutput);
            }

            if (this.开胶后延时时间>0)
            {
                MotionItemDelay motionItemDelay = new MotionItemDelay();
                motionItemDelay.dDelayTime = this.开胶后延时时间;
                motionItems.Add(motionItemDelay);
            }


            double dSweeAngle = GetArcStartAndEndAngle();
            if (U不跟随)
            {
                dSweeAngle = 0;
            }
            MotionItemArc motionItemArc=new MotionItemArc(spdXYGlue, PosStartTransfer, PosMidTransfer, PosEndTransfer, IsCW(), dSweeAngle);
            motionItemArc.dEndU= PosEndTransfer.U;
            motionItems.Add(motionItemArc);
            if (bIsContinueWithAferAndAfterIsOnGlue == false)
            {
                MotionItemOutput motionItemOutput = new MotionItemOutput();
                motionItemOutput.On = false;
                motionItemOutput.dEndU = PosEndTransfer.U;
                motionItems.Add(motionItemOutput);
                
            }
            if (bContinueWithAferItem == false)
            {
                MotionItemLine motionItemLineUp = new MotionItemLine(spdZH, PosEndTransfer);
                motionItemLineUp.Point.Z = gluePathUnit.全局安全高度Z;
                motionItemLineUp.dEndU = PosEndTransfer.U;
                motionItems.Add(motionItemLineUp);
            }
            #endregion
        }

        private void TranferPosToCur(GluePathUnit gluePathUnit,bool bContinueWithBeforeItem, List<MotionItemBase> motionItems,double dOffSet)
        {
            if (FrameManager.MachineStatus.Is4Axis == false)
                U不跟随 = true;
            if (U不跟随)
            {
                PointData PosStartTemp = new PointData(PosStart);
                PointData PosMidTemp = new PointData(PosMid);
                PointData PosEndTemp = new PointData(PosEnd);
                
                if (bContinueWithBeforeItem)
                {
                    PosStartTemp.U = motionItems[motionItems.Count - 1].dEndU;
                    PosMidTemp.U = motionItems[motionItems.Count - 1].dEndU;
                    PosEndTemp.U = motionItems[motionItems.Count - 1].dEndU;
                }
                else
                {
                    PosMidTemp.U = PosStartTemp.U;
                    PosEndTemp.U = PosStartTemp.U ;
                }

                PointData pointDataLocalStart = WhereAtLocal(PosStartTemp, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                PosStartTransfer = TranLocalToMotor(pointDataLocalStart, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, PosStartTransfer);

                PointData pointDataLocalMid = WhereAtLocal(PosMidTemp, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                PosMidTransfer = TranLocalToMotor(pointDataLocalMid, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, PosMidTransfer);

                PointData pointDataLocalEnd = WhereAtLocal(PosEndTemp, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                PosEndTransfer = TranLocalToMotor(pointDataLocalEnd, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, PosEndTransfer);
            }
            else
            {
                PointData PosStartTemp = new PointData(PosStart);
                PointData PosMidTemp = new PointData(PosMid);
                PointData PosEndTemp = new PointData(PosEnd);
                double dSweeAngle = GetArcStartAndEndAngle();
                if (bContinueWithBeforeItem)
                {
                    PosStartTemp.U = motionItems[motionItems.Count - 1].dEndU;
                    PosMidTemp.U = motionItems[motionItems.Count - 1].dEndU + dSweeAngle / 2;
                    PosEndTemp.U = motionItems[motionItems.Count - 1].dEndU + dSweeAngle;
                }
                else
                {
                    PosMidTemp.U = PosStartTemp.U + dSweeAngle / 2;
                    PosEndTemp.U = PosStartTemp.U + dSweeAngle;
                }

                PointData pointDataLocalStart = WhereAtLocal(PosStartTemp, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                PosStartTransfer = TranLocalToMotor(pointDataLocalStart, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, PosStartTransfer);



                PointData pointDataLocalMid = WhereAtLocal(PosMidTemp, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                PosMidTransfer = TranLocalToMotor(pointDataLocalMid, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, PosMidTransfer);

                PointData pointDataLocalEnd = WhereAtLocal(PosEndTemp, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                PosEndTransfer = TranLocalToMotor(pointDataLocalEnd, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, PosEndTransfer);
            }
            PosStartTransfer.Z = PosStartTransfer.Z - dOffSet;
            PosMidTransfer.Z = PosMidTransfer.Z - dOffSet;
            PosEndTransfer.Z = PosEndTransfer.Z - dOffSet;
        }

        private double GetArcStartAndEndAngle()
        {
            double xPos1, yPos1, xPos2, yPos2, xPos3, yPos3;
            xPos1 = PosStart.X;
            yPos1 = PosStart.Y;
            xPos2 = PosMid.X;
            yPos2 = PosMid.Y;
            xPos3 = PosEnd.X;
            yPos3 = PosEnd.Y;
            double xCenterPos; double yCenterPos; double dR;
            double dSweeAngle;
            if (GetCircle(xPos1, yPos1, xPos2, yPos2, xPos3, yPos3, out xCenterPos, out yCenterPos, out dR) == false)
                return 0;
            double dStartAnglePi = Math.Atan2(yPos1 - yCenterPos, xPos1 - xCenterPos);
            double dStartAngle = 180 * dStartAnglePi / Math.PI;
            double dMidAnglePi = Math.Atan2(yPos2 - yCenterPos, xPos2 - xCenterPos);
            double dMidAngle = 180 * dMidAnglePi / Math.PI;
            double dEndAnglePi = Math.Atan2(yPos3 - yCenterPos, xPos3 - xCenterPos);
            double dEndAngle = 180 * dEndAnglePi / Math.PI;
            dSweeAngle = dEndAngle - dStartAngle;
            if (dSweeAngle > 0)
            {
                if (dMidAngle > dStartAngle && dMidAngle < dEndAngle)
                {
                    dSweeAngle = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle = -(360 - (dEndAngle - dStartAngle));
                }
            }
            else
            {
                if (dMidAngle < dStartAngle && dMidAngle > dEndAngle)
                {
                    dSweeAngle = dEndAngle - dStartAngle;
                }
                else
                {
                    dSweeAngle = (360 - (dStartAngle - dEndAngle));
                }
            }
            return dSweeAngle;
        }
    }
}
